package org.openstack4j.openstack.networking.domain;

import com.fasterxml.jackson.annotation.JsonTypeInfo;
import com.fasterxml.jackson.databind.DatabindContext;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.jsontype.impl.TypeIdResolverBase;
import com.fasterxml.jackson.databind.type.SimpleType;
import org.openstack4j.model.network.QosRuleType;

/**
 * Created by yaowj on 2018/10/29.
 */
public class NeutronQosRuleInfoResolver extends TypeIdResolverBase {

    enum NeutronQosRule {
        BANDWIDTH_LIMIT(QosRuleType.BANDWIDTH_LIMIT, NeutronQosBandwidthLimitRuleInfo.class),
        DSCP_MARKING(QosRuleType.DSCP_MARKING, NeutronQosDscpMarkingRuleInfo.class),
        MINIMUM_BANDWIDTH(QosRuleType.MINIMUM_BANDWIDTH, NeutronQosMinimumBandwidthRuleInfo.class);


        private QosRuleType type;
        private Class clazz;

        NeutronQosRule(QosRuleType type, Class clazz) {
            this.type = type;
            this.clazz = clazz;
        }

        public static NeutronQosRule getByClazz(Class clazz){
            NeutronQosRule result = null;
            for(NeutronQosRule rule : NeutronQosRule.values()){
                if(rule.getClazz() == clazz){
                    result = rule;
                    break;
                }
            }
            return result;
        }



        public static NeutronQosRule getByTypeStr(String typeStr){
            NeutronQosRule result = null;
            for(NeutronQosRule rule : NeutronQosRule.values()){
                if(rule.getType().toJson().equals(typeStr)){
                    result = rule;
                    break;
                }
            }
            return result;
        }

        public QosRuleType getType() {
            return type;
        }

        public Class getClazz() {
            return clazz;
        }
    }

    @Override
    public String idFromValue(Object o) {

        NeutronQosRule rule = NeutronQosRule.getByClazz(o.getClass());
        if(rule == null){
            throw new IllegalArgumentException();
        }
        return rule.getType().toJson();
    }

    @Override
    public String idFromValueAndType(Object o, Class<?> aClass) {
        return idFromValue(o);
    }

    @Override
    public JsonTypeInfo.Id getMechanism() {
        return JsonTypeInfo.Id.CUSTOM;
    }

    @Override
    public JavaType typeFromId(DatabindContext context, String id) {
        NeutronQosRule rule = NeutronQosRule.getByTypeStr(id);
        if(rule == null){
            throw new IllegalArgumentException();
        }
        return SimpleType.constructUnsafe(rule.getClazz());
    }
}
